# 类定义
class People:
    # 定义基本操作
    name = ''
    age = 0
    # 定义私有属性，私有属性在类外部无法直接访问
    __weight = 0

    # 定义构造方法
    def __init__(self, n, a, w):
        self.name = n
        self.age = a
        self.__weight = w

    def speak(self):
        print('%s说：我%d岁。' % (self.name, self.age))


# 单继承示例
class Student(People):
    grade = ''

    def __init__(self, n, a, w, g):
        # 调用父类的构造函数
        People.__init__(self, n, a, w)
        self.grade = g

    # 复写父类的方法
    def speak(self):
        print('%s说：我%d岁了，在读%d年级。' % (self.name, self.age, self.grade))


# 另一个类，多重继承之前的准备
class Speaker:
    name = ''
    topic = ''

    def __init__(self, n, t):
        self.name = n
        self.topic = t

    def speak(self):
        print('我叫%s，今天演讲主题是%s' % (self.name, self.topic))


# 需要注意圆括号中父类的顺序，若是父类中有相同的方法名，而在子类使用时未指定，Python 从左至右搜索
# 即方法在子类中未找到时，从左到右查找父类中是否包含方法。
# 多重继承示例
class Sample01(Speaker, Student):
    a = ''

    def __init__(self, n, a, w, g, t):
        Student.__init__(self, n, a, w, g)
        Speaker.__init__(self, n, t)


# 方法名相同，此处父类Speaker和父类Student中的方法都有speak，默认调用在括号中排前的父类方法
# 因此Sample01调用的是父类Speaker中的方法
test = Sample01("tim", 25, 80, 4, 'python')
test.speak()
# 我叫tim，今天演讲主题是python


class Sample02(Student, Speaker):
    a = ''

    def __init__(self, n, a, w, g, t):
        Student.__init__(self, n, a, w, g)
        Speaker.__init__(self, n, t)


# 方法名相同，默认调用在括号中排前的父类方法
# 因此Sample02调用的是父类Student中的方法
test = Sample02("tim", 25, 80, 4, 'python')
test.speak()
# tim说：我25岁了，在读4年级。
